package com.study.example.gameserver.module.ranklist.entity;

import com.sparrow.cache.annotation.Cache;
import com.sparrow.cache.annotation.CacheType;
import com.sparrow.cache.entity.AbstractEntity;
import com.sparrow.common.handler.HandlerManager;
import com.sparrow.common.ranklist.RankElement;
import com.study.example.gameserver.module.ranklist.domain.RankType;
import com.study.example.gameserver.module.ranklist.handler.RankHandler;
import org.jetbrains.annotations.NotNull;

import javax.persistence.*;

@Cache(cacheType = CacheType.NONE)
@Entity
@IdClass(PlayerRankId.class)
@Table(name = "PlayerRank")
public class PlayerRank extends AbstractEntity<PlayerRankId> implements RankElement<PlayerRank> {

    @Id
    private Long playerId;

    @Id
    private Integer rankType;

    private String playerName;

    private int rank;

    private String rankDataStr;

    private transient Object rankData;

    private transient RankHandler handler;


    @Override
    public PlayerRankId getPK() {
        return new PlayerRankId(playerId, rankType);
    }

    @Override
    public long dispatchCode() {
        return playerId;
    }

    @Override
    public Long getRankElementId() {
        return playerId;
    }

    @Override
    public int getRank() {
        return rank;
    }

    @Override
    public void setRank(int rank) {
        this.rank = rank;
    }

    /**
     * 排序委托给 Handler
     */
    @Override
    public int compareTo(@NotNull PlayerRank o) {
        return handler.compare(this.rankData, o.rankData);
    }

    @Override
    public void deSerialize() {
        checkInitHandler();
        this.rankData = this.handler.decode(rankDataStr);
    }

    private void checkInitHandler() {
        if (this.handler == null) {
            this.handler = HandlerManager.getInstance()
                    .getHandler(RankHandler.class, RankType.of(rankType));
        }
    }

    @Override
    public void serialize() {
        checkInitHandler();
        this.rankDataStr = this.handler.encode(this.rankData);
    }

    public String getRankDataStr() {
        return rankDataStr;
    }

    public void setRankDataStr(String rankDataStr) {
        this.rankDataStr = rankDataStr;
    }

    public Object getRankData() {
        return rankData;
    }

    public void setRankData(Object rankData) {
        this.rankData = rankData;
    }

    public Integer getRankType() {
        return rankType;
    }

    public void setRankType(Integer rankType) {
        this.rankType = rankType;
    }

    public Long getPlayerId() {
        return playerId;
    }

    public void setPlayerId(Long playerId) {
        this.playerId = playerId;
    }

    public RankHandler getHandler() {
        return handler;
    }

    public void setHandler(RankHandler handler) {
        this.handler = handler;
    }

    public String getPlayerName() {
        return playerName;
    }

    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }
}
